package ca.scotthyndman.as2haxe.dom.binding;

import java.util.Set;

import ca.scotthyndman.as2haxe.dom.ASTNode;

/**
 * Represents a named actionscript element.
 * 
 */
public interface IBinding {

	/**
	 * Describes types of bindings.
	 * @author scottyhyndman
	 *
	 */
	public enum BindingKind {
		/**
		 * Kind constant (value 1) indicating a package binding.
		 * Bindings of this kind can be safely cast to <code>IPackageBinding</code>.
		 * 
		 * @see #getKind()
		 * @see IPackageBinding
		 */
		PACKAGE,
		
		/**
		 * Kind constant (value 2) indicating a type binding. Bindings of this kind
		 * can be safely cast to <code>ITypeBinding</code>.
		 * 
		 * @see #getKind()
		 * @see ITypeBinding
		 */
		TYPE,

		/**
		 * Kind constant (value 3) indicating a field or local variable binding.
		 * Bindings of this kind can be safely cast to <code>IVariableBinding</code>.
		 * 
		 * @see #getKind()
		 * @see IVariableBinding
		 */
		VARIABLE,

		/**
		 * Kind constant (value 4) indicating a method or constructor binding.
		 * Bindings of this kind can be safely cast to <code>IMethodBinding</code>.
		 * 
		 * @see #getKind()
		 * @see IMethodBinding
		 */
		METHOD,
	}

	/**
	 * Returns the kind of bindings this is. That is one of the kind constants:
	 * <code>PACKAGE</code>, <code>TYPE</code>, <code>VARIABLE</code>,
	 * <code>METHOD</code>,
	 * <p>
	 * Note that additional kinds might be added in the future, so clients
	 * should not assume this list is exhaustive and should program defensively,
	 * e.g. by having a reasonable default in a switch statement.
	 * </p>
	 * 
	 * @return one of the kind constants
	 */
	public BindingKind getKind();

	/**
	 * Returns the AST node associated with this binding
	 * 
	 * @return the AST node
	 */
	public ASTNode getASTNode();

	/**
	 * Sets the binding manager
	 * 
	 * @param mgr
	 */
	public void setBindingManager(BindingManager mgr);

	/**
	 * Returns the key for this binding.
	 * <p>
	 * Within a connected cluster of bindings (for example, all bindings
	 * reachable from a given AST), each binding will have a distinct keys. The
	 * keys are generated in a manner that is predictable and as stable as
	 * possible. This last property makes these keys useful for comparing
	 * bindings between disconnected clusters of bindings (for example, the
	 * bindings between the "before" and "after" ASTs of the same compilation
	 * unit).
	 * </p>
	 * <p>
	 * The exact details of how the keys are generated is unspecified. However,
	 * it is a function of the following information:
	 * <ul>
	 * <li>packages - the name of the package (for an unnamed package, some
	 * internal id)</li>
	 * <li>classes or interfaces - the VM name of the type and the key of its
	 * package</li>
	 * <li>array types - the key of the component type and number of dimensions</li>
	 * <li>primitive types - the name of the primitive type</li>
	 * <li>fields - the name of the field and the key of its declaring type</li>
	 * <li>methods - the name of the method, the key of its declaring type, and
	 * the keys of the parameter types</li>
	 * <li>constructors - the key of its declaring class, and the keys of the
	 * parameter types</li>
	 * <li>local variables - the name of the local variable, the index of the
	 * declaring block relative to its parent, the key of its method</li>
	 * <li>local types - the name of the type, the index of the declaring block
	 * relative to its parent, the key of its method</li>
	 * <li>anonymous types - the occurence count of the anonymous type relative
	 * to its declaring type, the key of its declaring type</li>
	 * <li>enum types - treated like classes</li>
	 * <li>annotation types - treated like interfaces</li>
	 * <li>type variables - the name of the type variable and the key of the
	 * generic type or generic method that declares that type variable</li>
	 * <li>wildcard types - the key of the optional wildcard type bound</li>
	 * <li>capture type bindings - the key of the wildcard captured</li>
	 * <li>generic type instances - the key of the generic type and the keys of
	 * the type arguments used to instantiate it, and whether the instance is
	 * explicit (a parameterized type reference) or implicit (a raw type
	 * reference)</li>
	 * <li>generic method instances - the key of the generic method and the
	 * keys of the type arguments used to instantiate it, and whether the
	 * instance is explicit (a parameterized method reference) or implicit (a
	 * raw method reference)</li>
	 * <li>members of generic type instances - the key of the generic type
	 * instance and the key of the corresponding member in the generic type</li>
	 * </ul>
	 * </p>
	 * <p>
	 * Note that the key for annotation bindings and member value pair bindings
	 * is not yet implemented. This returns <code>null</code> for these 2
	 * kinds of bindings.
	 * </p>
	 * 
	 * @return the key for this binding
	 */
	public String getKey();

	/**
	 * Returns a set of all AST nodes that refer to this binding.
	 * 
	 * @return The referred nodes.
	 */
	public Set<ASTNode> getReferringNodes();
}
